package Thread;

import java.util.PriorityQueue;

//自己模拟实现一个定时器；
//1.创建一个定时器任务类；
//2.创建一个定时器类，接受任务类，在定时器类进行执行该任务类；
//定时器类通过创建一个线程进行实现这个任务类；
class MyTimeTake implements Comparable<MyTimeTake>{
    private Runnable take;
    private long time;
    public MyTimeTake(Runnable take ,long time){
        this.take=take;
        this.time=time;
    }
    //任务启动方法；
    public void run(){
        take.run();
    }
    //获取任务时间的方法：
    public long getTime(){
        return time;
    }
    //比较那个任务先进行执行的方法；
    @Override
    public int compareTo(MyTimeTake o) {
        return (int)(this.time-o.time);
    }
}
//自己实现一个定时器类：
class MyTimer{
    private PriorityQueue<MyTimeTake> queue=new PriorityQueue<>();
     private Object locker=new Object();
    public void schedule(Runnable take,long delay){
        synchronized (locker){
            MyTimeTake myTimeTake=new MyTimeTake(take,System.currentTimeMillis()+delay);
            queue.offer(myTimeTake);
            locker.notify();
        }
    }
    public MyTimer(){
                Thread thread=new Thread(()-> {
                    while (true) {
                        synchronized (locker) {
                            while (queue.isEmpty()) {
                                try {
                                    locker.wait();
                                } catch (InterruptedException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                                MyTimeTake take = queue.peek();
                                if (System.currentTimeMillis() < take.getTime()) {
                                    try {
                                        locker.wait(take.getTime() - System.currentTimeMillis());
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }
                                } else {
                                    take.run();
                                    queue.poll();
                                }
                            }
                    }
                });
                thread.start();
            }
        }

public class Demo38 {
    public static void main(String[] args){
        MyTimer myTimer=new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        },2000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        },1000);
        System.out.println("hello main");
    }
}
//错误：①schedule方法的参数问题；
//②自我实现的任务类参数的问题；
//③代码练习能力加强
// ④线程安全问题的考虑，以及synchronized加锁操作的正确使用；
// ⑤：多线程情况下，容易发生执行等待：学会按需等待；